package com.rock.securityresearch.equity

import cats.ApplicativeThrow
import cats.effect.{IO, Sync}
import com.rock.securityresearch.common.equity.*
import com.rock.securityresearch.equity.StockCode.StockCode
import com.rock.securityresearch.util.JsonUtil
import com.rock.securityresearch.util.http.Http
import com.rock.securityresearch.common.TimePeriod
import com.rock.securityresearch.domain.DateRange
import org.typelevel.log4cats.Logger

import java.text.SimpleDateFormat
import java.time.LocalDate

trait Stocks[F[_]] {
    def getQuotePrice(code: StockCode, range: DateRange): F[Option[List[HistoricalStockQuote]]]
}

object Stocks {
    import cats.syntax.functor.toFunctorOps
    import com.rock.securityresearch.common.*
    import io.circe.generic.auto.*
    import io.circe.parser.*
    import cats.syntax.flatMap.toFlatMapOps


    def make[F[_] : Sync : Logger: ApplicativeThrow](): Stocks[F] = {
        new Stocks[F] {
            override def getQuotePrice(code: StockCode, range: DateRange): F[Option[List[HistoricalStockQuote]]] = {
                val prefix = if (code.code.take(1) == "6") then "0" else "1"
                val url = s"http://quotes.money.163.com/service/chddata.html?code=$prefix$code&start=${range.start.formatWith()}&end=${range.end.formatWith()}"
                for {
                    r <- Http[F].get(url).map(r => if (r.isOk) then r else throw Exception(s"status not ok ${r.statusCode}"))
                    quotes <- ApplicativeThrow[F].fromTry(QuotePriceCsvParser.parse(r.body, "GBK"))
                } yield quotes
            }
        }
    }
}

 
case class StockQuery(code: String, startDate: LocalDate, endDate: LocalDate, period: TimePeriod) {
    def toDateRange(): DateRange = {
        period match
            case TimePeriod.Daily => DateRange(startDate, endDate)
            case TimePeriod.Weekly => {
                val dow = endDate.getDayOfWeek
                ???
            }
            case TimePeriod.Monthly => ???
            case TimePeriod.Yearly => ???
    }
}